package org.dromara.event.service.impl;

import cn.hutool.core.bean.BeanUtil;
import lombok.Data;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.event.domain.EventAudit;
import org.dromara.event.domain.bo.EventAuditBo;
import org.dromara.event.domain.vo.EventAuditVo;
import org.dromara.event.mapper.EventAuditMapper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysOssService;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.dromara.event.domain.bo.EventDataBo;
import org.dromara.event.domain.vo.EventDataVo;
import org.dromara.event.domain.EventData;
import org.dromara.event.mapper.EventDataMapper;
import org.dromara.event.service.IEventDataService;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 活动Service业务层处理
 *
 * @author Lion Li
 * @date 2025-04-24
 */
@RequiredArgsConstructor
@Service
public class EventDataServiceImpl implements IEventDataService {

    private final EventDataMapper baseMapper;

    private final ISysOssService ossService;

    private final EventAuditMapper eventAuditMapper;

    private final SysUserMapper sysUserMapper;


    /**
     * 查询活动
     *
     * @param id 主键
     * @return 活动
     */
    @Override
    public EventDataVo queryById(Long id){
        EventDataVo eventDataVo =  baseMapper.selectVoById(id);
        List<EventAuditVo> eventAuditsVo = eventAuditMapper.selectVoList(
            Wrappers.lambdaQuery(EventAudit.class)
                .eq(EventAudit::getEventId, id)
                .eq(EventAudit::getApplyStatus, "1")
        );
        sysUserMapper.selectList(
            Wrappers.lambdaQuery(SysUser.class)
                .in(
                    SysUser::getUserId,
                    eventAuditsVo.stream().map(EventAuditVo::getUserId).toList()
                )
        ).forEach(sysUser -> {
            eventAuditsVo.forEach(eventAuditVo -> {
                if (sysUser.getUserId().equals(eventAuditVo.getUserId())){
                    eventAuditVo.setAvatarUrl( ossService.getById(sysUser.getAvatar()).getUrl());
                }
            });
        });
        eventDataVo.setEventAudits(eventAuditsVo);
        return eventDataVo;
    }

    /**
     * 分页查询活动列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 活动分页列表
     */
    @Override
    public TableDataInfo<EventDataVo> queryPageList(EventDataBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EventData> lqw = buildQueryWrapper(bo);
        Page<EventDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的活动列表
     *
     * @param bo 查询条件
     * @return 活动列表
     */
    @Override
    public List<EventDataVo> queryList(EventDataBo bo) {
        LambdaQueryWrapper<EventData> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<EventData> buildQueryWrapper(EventDataBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EventData> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(EventData::getId);
        lqw.like(StringUtils.isNotBlank(bo.getTitle()), EventData::getTitle, bo.getTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditStatus()), EventData::getAuditStatus, bo.getAuditStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditDetails()), EventData::getAuditDetails, bo.getAuditDetails());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), EventData::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), EventData::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getDescription()), EventData::getDescription, bo.getDescription());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), EventData::getAddress, bo.getAddress());
        lqw.between(params.get("beginEndTime") != null && params.get("endEndTime") != null,
            EventData::getEndTime ,params.get("beginEndTime"), params.get("endEndTime"));
        return lqw;
    }

    /**
     * 新增活动
     *
     * @param bo 活动
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(EventDataBo bo) throws IOException {
        if (bo.getImage().isEmpty()){
            throw new IOException("请上传图片");
        }
        EventData add = MapstructUtils.convert(bo, EventData.class);
        add.setCreateBy(LoginHelper.getUserId());
        add.setCreateDept(LoginHelper.getDeptId());
        add.setUpdateTime(new Date());
        add.setCreateTime(new Date());
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        EventAudit eventAudit = new EventAudit();
        eventAudit.setEventId(add.getId());
        eventAudit.setUserId(LoginHelper.getUserId());
        eventAudit.setApplyStatus("1");
        eventAudit.setAuditUserId(LoginHelper.getUserId());
        eventAudit.setAuditRemark("活动申请");
        eventAudit.setUpdateTime(new Date());
        eventAudit.setCreateTime(new Date());
        eventAuditMapper.insert(eventAudit);
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    public String uploadImage(MultipartFile file) throws IOException {
        //把图片保存到本地
        SysOssVo oss = ossService.upload(file);
        oss = ossService.getById(oss.getOssId());
        String avatar = oss.getUrl();
        return avatar;
    }

    /**
     * 修改活动
     *
     * @param bo 活动
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(EventDataBo bo) {
        EventData update = MapstructUtils.convert(bo, EventData.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(EventData entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除活动信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public Boolean audit(EventDataBo bo) {
        EventData update = MapstructUtils.convert(bo, EventData.class);
        update.setUpdateTime(new Date());
        update.setUpdateBy(LoginHelper.getUserId());
        if (bo.getAuditStatus().equals("1")){
            update.setStatus("1");
        }
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public TableDataInfo<EventDataVo> my(EventDataBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EventAudit> lqw = Wrappers.lambdaQuery();
        lqw.eq(EventAudit::getUserId, LoginHelper.getUserId());
        List<EventAudit> eventAudits = eventAuditMapper.selectList(lqw);
        List<Long> eventIds = eventAudits.stream().map(EventAudit::getEventId).collect(Collectors.toList());
        if (eventIds.isEmpty()){
            return TableDataInfo.build();
        }
        LambdaQueryWrapper<EventData> lqw1 = buildQueryWrapper(bo);
        lqw1.in(EventData::getId, eventIds);
        Page<EventDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw1);
        return TableDataInfo.build(result);

    }

    @Override
    public List<EventDataVo> random() {
        //随机抽四张图片和活动id作为轮播图  随机！！
        List<EventDataVo> eventDataVos = baseMapper.selectVoList(new LambdaQueryWrapper<EventData>().eq(EventData::getStatus, "1"));
        if (eventDataVos.size() < 4){
            return eventDataVos;
        }else{
            //随机拿四个返回
            List<EventDataVo> eventDataVos1 = new ArrayList<>();
            for (int i = 0; i < 4; i++) {
                //取0-eventDataVos.size的随机数
                int random = (int) (Math.random() * eventDataVos.size());
                eventDataVos1.add(eventDataVos.get(random));
                eventDataVos.remove(random);
            }
            return eventDataVos1;
        }


    }


}
